package com.pkk.cloud.support.admin.service.impl;

import static com.pkk.cloud.support.admin.constand.OauthAdminConstand.DEFAULT_RESOURCE_TYPE_CLIENT;
import static com.pkk.cloud.support.admin.constand.OauthAdminConstand.DEFAULT_RESOURCE_TYPE_SERVER;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pkk.cloud.support.admin.bo.OauthServerClientBo;
import com.pkk.cloud.support.admin.bo.RoleClientCateAndMenuResourceSimpeBo;
import com.pkk.cloud.support.admin.bo.RoleClientResourceSimpeBo;
import com.pkk.cloud.support.admin.dto.req.resources.OauthClientRoleResourcesReqDto;
import com.pkk.cloud.support.admin.dto.req.server.OauthServerIdReqDto;
import com.pkk.cloud.support.admin.dto.req.server.OauthServerPageSearchReqDto;
import com.pkk.cloud.support.admin.dto.resp.client.OauthClientServerSimpleRespDto;
import com.pkk.cloud.support.admin.dto.resp.server.OauthServerClientSimpleRespDto;
import com.pkk.cloud.support.admin.dto.resp.server.OauthServerListRespDto;
import com.pkk.cloud.support.admin.dto.resp.server.RoleClientResourceSimpeRespDto;
import com.pkk.cloud.support.admin.entity.resource.PenguinSysServer;
import com.pkk.cloud.support.admin.mybatis.resource.PenguinSysServerMapper;
import com.pkk.cloud.support.admin.service.PenguinSysResourceService;
import com.pkk.cloud.support.admin.service.PenguinSysServerService;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author peikunkun<br>
 * @version V1.0<br>
 * @Title: 系统服务组(客户端组的操作)<br>
 * @Description: <><br>
 * @date 2020/4/10 0010 上午 11:28<br>
 * @URL:[]
 */
@Slf4j
@Service
public class PenguinSysServerServiceImpl extends ServiceImpl<PenguinSysServerMapper, PenguinSysServer> implements
    PenguinSysServerService {

  @Resource
  private PenguinSysResourceService penguinSysResourceService;

  /**
   * @Description: 保存服务(客户端组)
   * @Param: server
   * @return: boolean
   * @Author: peikunkun
   * @Date: 2020/4/1 0001 下午 9:25
   */
  @Override
  public boolean saveSysServerService(PenguinSysServer server) {
    return baseMapper.insert(server) == 1;
  }


  /**
   * @Description: 删除服务(客户端组)
   * @Param: id
   * @return: boolean
   * @Author: peikunkun
   * @Date: 2020/4/1 0001 下午 9:36
   */
  @Override
  @Transactional
  public boolean delSysServerServiceById(Long[] ids) {
    for (int i = 0; i < ids.length; i++) {
      baseMapper.updateById(PenguinSysServer.builder().isDeleted(true).id(ids[i]).build());
    }
    return true;
  }

  /**
   * @Description: 更新id依据服务信息
   * @Param: server
   * @return: boolean
   * @Author: peikunkun
   * @Date: 2020/4/1 0001 下午 9:40
   */
  @Override
  public boolean updateSysServerServiceById(PenguinSysServer server) {
    return baseMapper.updateById(server) == 1;
  }

  /**
   * @Description: 返回服务信息(客户端组)的列表
   * @Param: body
   * @return: java.util.List<com.pkk.cloud.support.admin.dto.resp.server.OauthServerListRespDto>
   * @Author: peikunkun
   * @Date: 2020/4/1 0001 下午 9:45
   */
  @Override
  public List<OauthServerListRespDto> findSysServerServiceList(OauthServerPageSearchReqDto reqDto) {
    return baseMapper.findSysServerServiceList(reqDto);
  }

  /**
   * @Description: 依据服务端组id查询服务(客户端)信息
   * @Param: body
   * @return: java.util.List<com.pkk.cloud.support.admin.dto.resp.client.OauthClientServerSimpleRespDto>
   * @Author: peikunkun
   * @Date: 2020/4/5 0005 上午 12:29
   */
  @Override
  public List<OauthClientServerSimpleRespDto> getServerByServerGroupId(OauthServerIdReqDto body) {
    return baseMapper.getServerByServerGroupId(body);
  }

  /**
   * @Description: 获取服务客户端的信息
   * @return: java.util.List<com.pkk.cloud.support.admin.dto.resp.server.OauthServerClientSimpleRespDto>
   * @Author: peikunkun
   * @Date: 2020/4/9 下午7:13
   */
  @Override
  public List<OauthServerClientSimpleRespDto> getServerClient() {
    List<OauthServerClientSimpleRespDto> finalResult = new ArrayList<>();

    //获取服务端的信息
    List<OauthServerClientBo> server = this.findSysServerClientConvert();
    if (null == server || server.size() <= 0) {
      return finalResult;
    }

    //获取服务组端下面的所有客户端
    server.stream()
        .collect(Collectors.groupingBy(OauthServerClientBo::getServerCode, LinkedHashMap::new, Collectors.toList()))
        .forEach((serverCodeItem, serverClientList) -> {
          final String serverName = serverClientList.get(0).getServerName();
          final Long serverId = serverClientList.get(0).getServerId();
          List<OauthServerClientSimpleRespDto> childResult = new ArrayList<>();
          serverClientList.stream().forEach(childClient -> {
            childResult.add(OauthServerClientSimpleRespDto.builder().key(childClient.getClientId())
                .title(childClient.getClientName()).type(DEFAULT_RESOURCE_TYPE_CLIENT)
                .code(childClient.getClientCode()).primaryId(childClient.getId()).build());
          });
          finalResult.add(OauthServerClientSimpleRespDto.builder().key(serverCodeItem).title(serverName)
              .children(childResult).type(DEFAULT_RESOURCE_TYPE_SERVER).primaryId(serverId).build());
        });
    return finalResult;
  }

  /**
   * @Description: 获取角色与资源的的绑定关系树
   * @Param: body
   * @return: java.util.List<com.pkk.cloud.support.admin.dto.resp.server.RoleClientResourceSimpeRespDto>
   * @Author: peikunkun
   * @Date: 2020/4/9 下午9:57
   */
  @Override
  public List<RoleClientResourceSimpeRespDto> getRoleClientResource(OauthClientRoleResourcesReqDto body) {
    //获取所有的菜单
    List<RoleClientResourceSimpeBo> clientResource = penguinSysResourceService
        .findClientAllResourceByClientId(body.getClientId());

    //角色的已绑定的信息
    Set<Long> roleResource = new HashSet<>();
    if (null != body.getRoleId()) {
      roleResource = penguinSysResourceService.findRoleResourceIdByRoleId(body.getRoleId());
    }

    List<RoleClientResourceSimpeRespDto> finalResult = new ArrayList<>();
    //第一层分组【按照分类进行分组】
    Set<Long> finalRoleResource = roleResource;
    clientResource.stream()
        .collect(Collectors.groupingBy(RoleClientResourceSimpeBo::getCateId, LinkedHashMap::new, Collectors.toList()))
        .forEach((cateIdKey, cateGroupList) -> {
          //父级菜单是否选中,依据按钮进行判断
          AtomicBoolean superIsCheck = new AtomicBoolean();
          superIsCheck.set(true);

          final RoleClientResourceSimpeRespDto cateDto = new RoleClientResourceSimpeRespDto();
          List<RoleClientResourceSimpeRespDto> childMenuList = new ArrayList<>();
          //第二层分组【按照菜单进行分组】
          cateGroupList.stream().collect(
              Collectors.groupingBy(RoleClientResourceSimpeBo::getMenuId, LinkedHashMap::new, Collectors.toList()))
              .forEach((menuIdKey, menuGroupList) -> {
                //父级菜单是否选中,依据按钮进行判断
                AtomicBoolean menuIsCheck = new AtomicBoolean();
                menuIsCheck.set(true);
                final RoleClientResourceSimpeRespDto menuDto = new RoleClientResourceSimpeRespDto();
                List<RoleClientResourceSimpeRespDto> childBtnList = new ArrayList<>();
                //第三层按钮的处理
                menuGroupList.stream().forEach(btn -> {
                  //当按钮层有一个不勾选状态,父级全为不勾选状态
                  final boolean isNoContainsBtn = !finalRoleResource.contains(btn.getButId());
                  if (menuIsCheck.get() && isNoContainsBtn) {
                    menuIsCheck.set(false);
                    //只要菜单有一个是false,super就是false
                    superIsCheck.set(false);
                  }
                  childBtnList.add(RoleClientResourceSimpeRespDto.builder().id(btn.getButId()).resourcePid
                      (btn.getButResourcePid()).title(btn.getButTitle()).checked(!isNoContainsBtn).build());
                });

                menuDto.setId(menuGroupList.get(0).getMenuId());
                menuDto.setTitle(menuGroupList.get(0).getMenuTitle());
                menuDto.setResourcePid(menuGroupList.get(0).getMenuResourcePid());
                menuDto.setChecked(menuIsCheck.get());
                menuDto.setChildren(childBtnList);
                childMenuList.add(menuDto);

              });

          //添加子集
          cateDto.setId(cateGroupList.get(0).getCateId());
          cateDto.setTitle(cateGroupList.get(0).getCateTitle());
          cateDto.setResourcePid(cateGroupList.get(0).getCateResourcePid());
          cateDto.setChecked(superIsCheck.get());
          cateDto.setChildren(childMenuList);
          finalResult.add(cateDto);
        });
    return finalResult;
  }


  /**
   * @Description: 获取所有的角色与资源的关系树
   * @Param: body
   * @return: java.util.List<com.pkk.cloud.support.admin.dto.resp.server.RoleClientResourceSimpeRespDto>
   * @Author: peikunkun
   * @Date: 2020/4/9 下午9:57
   */
  @Override
  public List<OauthServerClientSimpleRespDto> getClientResource(String clientId) {
    //获取所有分类与菜单
    List<RoleClientCateAndMenuResourceSimpeBo> clientResource = penguinSysResourceService
        .findClientCateAndMenuResourceByClientId(clientId);

    List<OauthServerClientSimpleRespDto> finalResult = new ArrayList<>();
    //第一层分组【按照分类进行分组】
    clientResource.stream().collect(Collectors
        .groupingBy(RoleClientCateAndMenuResourceSimpeBo::getCateId, LinkedHashMap::new, Collectors.toList()))
        .forEach((cateIdKey, cateGroupList) -> {
          final OauthServerClientSimpleRespDto cateDto = new OauthServerClientSimpleRespDto();
          List<OauthServerClientSimpleRespDto> childMenuList = new ArrayList<>();

          //判断子菜单不为空的操作
          final long count = cateGroupList.stream().filter(a -> a.getMenuId() != null).count();
          if (cateGroupList.size() == count) {
            //第二层分组【按照菜单进行分组】
            cateGroupList.stream().collect(
                Collectors.groupingBy(RoleClientCateAndMenuResourceSimpeBo::getMenuId, LinkedHashMap::new,
                    Collectors.toList())).forEach((menuIdKey, menuGroupList) -> {
              final OauthServerClientSimpleRespDto menuDto = new OauthServerClientSimpleRespDto();
              menuDto.setTitle(menuGroupList.get(0).getMenuTitle());
              menuDto.setIcon(menuGroupList.get(0).getMenuClassIcon());
              menuDto.setCode(menuGroupList.get(0).getMenuResourceCode());
              menuDto.setPrimaryId(menuGroupList.get(0).getMenuId());
              menuDto.setType(menuGroupList.get(0).getMenuType());
              menuDto.setRouteUrl(menuGroupList.get(0).getMenuResourceUrl());
              menuDto.setKey(String.valueOf(menuGroupList.get(0).getMenuId()));
              childMenuList.add(menuDto);
            });
          }

          //添加菜单子集
          cateDto.setTitle(cateGroupList.get(0).getCateTitle());
          cateDto.setIcon(cateGroupList.get(0).getCateClassIcon());
          cateDto.setCode(cateGroupList.get(0).getCateResourceCode());
          cateDto.setPrimaryId(cateGroupList.get(0).getCateId());
          cateDto.setType(cateGroupList.get(0).getCateType());
          cateDto.setKey(String.valueOf(cateGroupList.get(0).getCateId()));
          cateDto.setChildren(childMenuList);
          finalResult.add(cateDto);
        });
    return finalResult;
  }

  /**
   * @Description: 获取转换之后的服务端信息
   * @Author: peikunkun
   * @Date: 2020/4/9 下午8:13
   */
  @Override
  public List<OauthServerClientBo> findSysServerClientConvert() {
    return baseMapper.findSysServerClientConvert();
  }
}
